public without sharing class GetUnfinishAssignTaskUtil {

    //public static Set<String> specialSet = new Set<String>{'系统管理员','销售部产品经理(集团)','销售管理部项目经理'};
/*
    @Future(callout=true)
    public static void asyncExcute(){
        execute();
    }

    public static void execute() {

    	Integer year = System.now().year();
    	Integer quarter = Integer.valueOf((System.now().month()-1) / 3 +1 );
    	//判断任务是否完成
    	String only = 'GetUnfinishAssignTaskShceduler'+year + quarter;
    	List<SchedulerExcuetLog__c> seList =  [select Id , Only__c,Message__c , IsFinished__c , Stage1__c,Stage2__c,Stage3__c,Stage4__c from SchedulerExcuetLog__c  where Only__c =:only ];
    	
    	///任务完成了
    	if(seList.size() >0 && seList[0].IsFinished__c == true) return;
    	SchedulerExcuetLog__c se = seList.size() >0 ? seList[0] : new SchedulerExcuetLog__c(Only__c = only);

		Map<String,String>companyMap = ImportObject.getPicklistValues('ApplicationForUnqualifiedDelive__c', 'Company__c', false);
    	//System.debug(companyMap);
    	//助里与公司的对应:
    	Map<String,String> assiMap =  new Map<String,String>();
    	 ///获取并验证助理是否在职

    	Map<String,String> assistantMap = new Map<String,String>();
    	for(String s : Label.NoteAssitant_UnqualifiedDelive.split(',') ){
    		String[] ss =s.split('-'); 
    		if(ss.size() > 0 )assistantMap.put(ss[0], ss[1]);
    		assiMap.put(companyMap.get(ss[0]), ss[1]);	

    	}
    	
    	for(User assi : [select Id ,Name,SubCompany__c ,IsActive from User where Id in: assistantMap.values() ] ){

    		if(assi.IsActive != true  ){
	    		 setErr(se,false,'有助理离职了请维护:Label.NoteAssitant_UnqualifiedDelive ');
	    		return;
    		}
    		if(!companyMap.containsKey(assi.SubCompany__c)){
    			setErr(se,false,'请维护'+assi.SubCompany__c+'的公司编码到全局列表值!');
	    		return;
    		}
    	}
    
        //System.debug('GetUnfinishAssignTaskShceduler==>'+ assiMap);

    	//阶段1 : 获取数据
    	List<Object> datas = null;
    	if(!se.Stage2__c || !se.Stage3__c ){

    		try {

    			datas = getDetails(year , quarter);
    			 se.Stage1__c = true;
    		}
    		catch (Exception e) {
    		    
    		    setErr(se,false, e.getMessage());

    		    return;

    		}
    		
    	}
    	if(datas != null && datas.size() == 0){
		  setErr(se,true,'未达成数据为空');
		    return;
    	}
    	 Map<String,Set<String>> accpkMap = new Map<String,Set<String>>();
    	//分发给销售员
    	if(!se.Stage2__c ||  !se.Stage3__c ){

    		SavePoint sp = Database.setSavepoint();
    		try {

    			///匹配客户 及销售员
    			Map<Id,Account> accMap = new Map<Id,Account>();
    			Set<Id> rmAccSet = new Set<Id>();

                //计算整体达成率
                Map<String,Map<String,Decimal>> allMap = new Map<String,Map<String,Decimal>>();


    			for(Object ob :datas){
                	Map<String,Object> m = (Map<String,Object>) ob;
                	//accMap.put(Id.valueOf(String.valueOf(m.get('ACCOUNTID'))), null);

                    String ke = String.valueOf(m.get('ACCOUNTID')) +'-'+  DataUtil.getStringValue(m.get('UNITCODE'));
                    //计算达成率
                    Map<String,Decimal> dcRito = allMap.containsKey(ke) ? allMap.get(ke) : new Map<String,Decimal>();
                    
                    dcRito.put('un',  dcRito.containsKey('un') ? dcRito.get('un')+toDecimal(DataUtil.getDecimalValue(m.get('UNFINISHTASK'))) : toDecimal(DataUtil.getDecimalValue(m.get('UNFINISHTASK'))));
                    //DataUtil.getDecimalValue(mo.get('TASK'));
                    dcRito.put('ta',  dcRito.containsKey('ta') ? dcRito.get('ta')+toDecimal(DataUtil.getDecimalValue(m.get('TASK'))) : toDecimal(DataUtil.getDecimalValue(m.get('TASK'))));

                    dcRito.put('cu',  dcRito.containsKey('cu') ? dcRito.get('cu')+toDecimal(DataUtil.getDecimalValue(m.get('CURRENTTASK'))) : toDecimal(DataUtil.getDecimalValue(m.get('CURRENTTASK'))));

                   allMap.put(ke,dcRito);


                }

                for(String k : allMap.keySet() ){
                    Map<String,Decimal> dcRito  =  allMap.get(k);
                    if(dcRito.get('un') > 0 ){
                        accMap.put(Id.valueOf(k.split('-')[0]), null );
                    }else{
                    	rmAccSet.add(Id.valueOf(k.split('-')[0]));
                    }

                }
               // System.debug('GetUnfinishAssignTaskShceduler==>'+ allMap);

               // System.debug('GetUnfinishAssignTaskShceduler==>'+ accMap);
                //查找客户及销售员
                for(Account acc : [select Name,System__c ,Id,OwnerId ,Owner.IsActive,Owner.Profile.Name,Owner.SubCompany__c,IfMoreCompany__c ,NCICCode__c,RecordType.DeveloperName ,WhetherOpenBusiness__c, 
                	(select Id ,UserId,User.subcompany__c,User.IsActive,User.Profile.Name from AccountTeamMembers   )
                	from Account where Id in: accMap.keySet()]){

                	accMap.put(acc.Id , acc);

                }
                System.debug('GetUnfinishAssignTaskShceduler==>'+ accMap);
                //[{"CURRENTTASK":"6","INVCLSFYJNAME":"血液","TASK":"6","PK_CUBASDOC":"0001A010000000687O2A","UNFINISHTASK":"3.0539","UNITCODE":"MKSY","ACCOUNTID":"0010I00001ak46XQAQ"}]
                if(System.Test.isRunningTest()){
                    Account acc = new Account();
                    acc.Id = '0010I00001ak46XQAQ';
                    acc.NCICCode__c = '0001A010000000687O2A';
                    acc.System__c = '美年';
                    acc.OwnerId = UserInfo.getUserId();
                    acc.IfMoreCompany__c = true;
                    accMap.put(acc.Id, acc);

                }

                
				 * NC 控制经销商发货
				 * 1.普通经销商  开票公司 ===>  归口公司 ==> 分发给对应 归口公司 的销售员  ==> 没有找到分发给 对应公司的助理 ==>  没有助理,报错
				 * 2.代开业务经销商   开票公司 ===> 实业/生物 ==> 分发给对应 归口公司 的销售员 ==> 没有找到分发给 对应公司 的助理 ==>  没有助理,报错
				 * 3.特殊经销商    控制 ===> 所有子公司都控制  ==>  分发给指定的人(集团) ==>  没有找到或离职 报错
                
                //主表
    			List<ApplicationForUnqualifiedDelive__c> afdList = new List<ApplicationForUnqualifiedDelive__c>();
    			//明细表
    			Map<String  ,List<ApplicationForUnqualifiedDeliveDetail__c>> adMap  = new Map<String ,List<ApplicationForUnqualifiedDeliveDetail__c>> ();
                
                for(Object ob :datas){
                	
                	Map<String,Object> mo = (Map<String,Object>) ob;

		    		String companycode = DataUtil.getStringValue(mo.get('UNITCODE'));//归口公司

			    	Id  accId = Id.valueOf(DataUtil.getStringValue(mo.get('ACCOUNTID')));

			    	if(rmAccSet.contains(accId))continue;
    				Account acc = accMap.get(accId );
    				//Boolean IsSpecail =  Label.TaskSpecialAccount.contains(String.valueOf(accId).substring(0,15));

                    //System.debug('GetUnfinishAssignTaskShceduler==> '+ accId +' ');


    				if(acc == null ){
    					//continue;
    					throw new DmlException(accId +'客户不存在!');
    				}


                   // System.debug('GetUnfinishAssignTaskShceduler==> '+ acc.RecordType.DeveloperName);
    					//需要在NC控制 的经销商
    				if( acc.RecordType.DeveloperName == 'Dealer' || acc.System__c != null ){

    					if(acc.NCICCode__c == null ){
    						//continue;
    						acc.NCICCode__c =  DataUtil.getStringValue(mo.get('PK_CUBASDOC')); 
    						//throw new DmlException(accId +'请维护客户识别码!');
    					}else{
    						//System.debug('GetUnfinishAssignTaskShceduler==> '+ accId);
    					}

    					// if(IsSpecail){

    					// 	for(String subcom : companyMap.values()){
	    				// 		accpkMap = addPks(subcom,acc.NCICCode__c,accpkMap);
    					// 	}

    					// }else 
                        //如果 是代开业务或者多归口公司 的客户
                        if(acc.WhetherOpenBusiness__c == true || acc.IfMoreCompany__c == true ){
                            for(String subcom : companyMap.values()){
                                accpkMap = addPks(subcom,acc.NCICCode__c,accpkMap);
                            }
    					
    					}else{//
    						accpkMap = addPks(companycode,acc.NCICCode__c,accpkMap);

    					}
    				}

    				 if(!se.Stage2__c){

    				 	ApplicationForUnqualifiedDeliveDetail__c ad = new ApplicationForUnqualifiedDeliveDetail__c();
			    		
                        ad.ProductLine__c = String.valueOf(mo.get('INVCLSFYJNAME'));
			    		ad.TaskMargin__c = toDecimal(DataUtil.getDecimalValue(mo.get('UNFINISHTASK')));
			    		ad.QuarterlyTaskVolume__c  = toDecimal(DataUtil.getDecimalValue(mo.get('CURRENTTASK')));
                        Decimal t =  toDecimal(DataUtil.getDecimalValue(mo.get('TASK')));

                        ad.TaskAchievementRate__c = t == null || t == 0  ? 0 : (1 - (ad.TaskMargin__c == null ? 0 : ad.TaskMargin__c )/t ) * 100 ;


			    		Id OwnerId =  null ;
                        
                        *
                        try{
                                OwnerId = Label.SpecialAccount.split('-')[1];
                            }catch(Exception e ){
                                throw new DmlException(accId +'找不到Label.SpecialAccount指定人员!');
                            }


                        *
                            //代开客户和 多 归口客户
			    		if(acc.WhetherOpenBusiness__c == true || acc.IfMoreCompany__c == true  ){

	    				 	 OwnerId = assiMap.get(companycode);

			    		}else{//普通客户

                            OwnerId = companyMap.get(acc.Owner.SubCompany__c) == companycode ?(acc.Owner.IsActive ? (specialSet.contains(acc.Owner.Profile.Name) ? null :  acc.OwnerId) :null)  : getSalerId(companycode,acc ,companyMap);
                           
                            if(OwnerId == null) OwnerId = assiMap.get(companycode);
                            
			    			//assiMap.get(companycode);
			    		}
	    				if(OwnerId == null ){

	    				
	    					//continue;
    						throw new DmlException(accId +'找不到对应的所有人!');
	    				}


	    				if(!adMap.containsKey(accId +'-'+ companycode )){
                            Map<String,Decimal> dcRitoMap = allMap.get(accId +'-'+ companycode);
                            Decimal ratio =(1- dcRitoMap.get('un') / dcRitoMap.get('ta')) * 100;

                            ApplicationForUnqualifiedDelive__c a;
                            afdList.add(new ApplicationForUnqualifiedDelive__c(Account__c=accId ,Year__c=String.valueOf(year)+'年',Quarter__c= getQuater(quarter),OwnerId =OwnerId,Company__c=companycode,TaskAchievementRate__c = ratio, TaskMargin__c = dcRitoMap.get('un'),QuarterlyTaskVolume__c = dcRitoMap.get('cu') ,IfMoreCompany__c = acc.IfMoreCompany__c ));

                        }
	    				List<ApplicationForUnqualifiedDeliveDetail__c> tmp = adMap.containsKey(accId+'-'+companycode) ? adMap.get(accId+'-'+companycode) : new  List<ApplicationForUnqualifiedDeliveDetail__c> ();
	    				tmp.add(ad);
	    				adMap.put(accId+'-'+companycode,tmp);

    				 }

                }

                //保存数据:
                if(!se.Stage2__c){


                	List<ApplicationForUnqualifiedDeliveDetail__c> adList = new List<ApplicationForUnqualifiedDeliveDetail__c>();
		    	    if(!System.Test.isRunningTest() && afdList.size() > 0 ) insert afdList;

                    List<Task> tList = new List<Task>();

		    	    for(ApplicationForUnqualifiedDelive__c afd : afdList){

                            Task ta = new Task();
                            ta.OwnerId = afd.OwnerId;
                            ta.WhatId = afd.Id ;
                            ta.Account__c  = afd.Account__c;
                            ta.Subject =  accMap.get(afd.Account__c).Name + '客户的'+year+'年'+quarter+'季度的迈克任务量未达标!!!';
                            ta.ActivityDate = System.today();
                            ta.Description = accMap.get(afd.Account__c).Name + '客户的'+year+'年'+quarter+'季度的迈克任务量未达标，若为经销商客户NC系统已限制发货，请尽快完成任务量未达标发货申请单的填写，提交审批成功后，NC系统才能解除限制，完成后可关闭此任务通知！';
                            tList.add(ta);


		    	    	List<ApplicationForUnqualifiedDeliveDetail__c> tmp = adMap.get(afd.Account__c+'-'+afd.Company__c);
		    	    	if(tmp != null  && tmp.size() > 0){
		    	    		for (ApplicationForUnqualifiedDeliveDetail__c ad  : tmp) {
		    	    			ad.ApplicationForUnqualifiedDelive__c = afd.Id;
		    	    			//ad.Id  = adexistMap.get(ad.ProductLine__c + afd.Account__c);
		    	    			adList.add(ad);
		    	    		}
		    	    		
		    	    	}
		    	    }


		    	    adMap.clear();
		    	    if(!System.Test.isRunningTest()&& afdList.size() > 0 ) upsert  adList;
                    if(!System.Test.isRunningTest() && tList.size() > 0 ) insert tList;
                    se.Stage2__c = true; 
                    se.Message__c = '保存数据成功!';
                    upsert se;
                    return;

                }

                
	             
    		}
    		catch (Exception e) {

    		    Database.rollback(sp);
                System.debug('GetUnfinishAssignTaskShceduler==>'+ e.getStackTraceString());
    		    se.Stage2__c = false;
    		    setErr(se,false,e.getMessage());
    		    return;

    		}

    	}

    	  System.debug('GetUnfinishAssignTaskShceduler==>'+ accpkMap);

    	//阶段3 
    	//经销商传到NC标记起来 同步到NC 
    	if(!se.Stage3__c){

    		try {
    				se.Stage2__c = true;
					se.Message__c = null;
    			if(accpkMap.keySet().size() ==  0 ){
    				se.Stage3__c = true;
    				se.IsFinished__c = true;
    				se.Message__c = '没有需要标记的客户!';
					upsert se;
    			}else{
    				
					upsert se;
                   

        				for (String comcode :accpkMap.keySet() ) {
    						
    					   Set<String> tmp = accpkMap.get(comcode);

        					if(tmp != null && tmp.size() > 0 ){

                                AsyncLockToNCQueueable locktoNc = new AsyncLockToNCQueueable();
                                locktoNc.comcode = comcode;
                                locktoNc.tmp = tmp;
                                System.enqueueJob(locktoNc);
        					   //GetUnfinishAssignTaskShceduler.sycnNC(comcode,new List<String>(tmp),'TEST1');
        				        
        					}

    				}
    				
    			}
    			
    		}catch (Exception e) {
    		    se.Stage3__c = false;
    		    setErr(se,false,e.getMessage());
    		    return;
    		    
    		}
    		
    	}

        
    }


    public static Decimal toDecimal(Decimal d ){
    	if(d == null ) return 0;
    	return d;
    }

     public  static String getQuater(Integer q){
    	if(q == 1) return '一季度';
    	if(q == 2) return '二季度';
    	if(q == 3) return '三季度';
        if(q == 4) return '四季度';
    	return null;

    }

    private static Map<String,Set<String>> addPks(String comkey ,String nciccode , Map<String,Set<String>> accpkMap){

    	Set<String> accpks = accpkMap.containsKey(comkey) ? accpkMap.get(comkey) : new Set<String>();
		accpks.add(nciccode);
		accpkMap.put(comkey, accpks);
		return accpkMap;


    }
    private static SchedulerExcuetLog__c setErr(SchedulerExcuetLog__c se,Boolean isf ,String message){

    	se.IsFinished__c = isf;
    	se.Message__c = message == null ? null : message.substring(0, message.length() >255 ? 255: message.length());
        upsert se;
        if(message != null ) sendMail(se.Id);
    	return se;
    }

    private static  Id getSalerId(String comcode ,Account acc,Map<String,String>cMap ){
    	Id oId = null;
    	for(AccountTeamMember t : acc.AccountTeamMembers ){

    		if(comcode == cMap.get(t.User.SubCompany__c)){
                if(specialSet.contains(t.User.Profile.Name) )continue;
                if(!t.User.IsActive)continue;
    			oId = t.UserId ;
    			break;
    		}
    	}
    	return oId ;
    }

    
	* year 当前年
	* quarter 当前季度
    
    private  static String getSql( Integer year ,Integer quarter ){
    	//	'round(sum(case when year_=\'2019\' and (FLOOR((ltrim(MONTH_,\'0\')-1)/3)+ 1)< 3 then nvl(ASSIGNAMOUNT__C,0) else null end),4) 本年截止上季度任务量, '+
		//	'round(sum(case when year_=\'2019\' and (FLOOR((ltrim(MONTH_,\'0\')-1)/3)+ 1)< 3 then nvl(TASKNMNY,0) else null end),4) 本年截止上季度已完成, '+

    	Integer lyear = year;
    	Integer lquarter = quarter -1 ;

    	if(lquarter == 0){
    		lquarter = 4;
    		lyear -= 1;
    	}

    	return 	' select '+
			   	' nvl(b.ACCOUNTID,c.ACCOUNTID) ACCOUNTID, '+
			   	'com.unitcode, '+
			   	'pk_cubasdoc,'+
				'INVCLSFYJNAME, '+
				'round(sum(case when year_=\''+lyear +'\' and (FLOOR((ltrim(MONTH_,\'0\')-1)/3)+ 1)<= '+lquarter+' then nvl(ASSIGNAMOUNT__C,0)-nvl(TASKNMNY,0) else null end),4) unfinishtask , '+
                'round(sum(case when year_=\''+lyear +'\' and (FLOOR((ltrim(MONTH_,\'0\')-1)/3)+ 1)<= '+lquarter+' then   nvl(ASSIGNAMOUNT__C,0) else null end),4)  task  , '+
				'round(sum(case when year_=\''+year +'\' and (FLOOR((ltrim(MONTH_,\'0\')-1)/3)+ 1)='+quarter+' then nvl(ASSIGNAMOUNT__C,0) else null end),4)  currenttask  '+
				'from FACT_SALETASK_CHFL a  '+
				'left join dim_company com on a.pk_corp_gk = com.pk_corp '+

				'left join stg_sf_account b on a.pk_cubasdoc=b.NCICCODE__C  '+
				'left join stg_sf_account c on a.ACCOUNTNAME__C=c.ACCOUNTNAME__C  '+
				'where nvl(b.ACCOUNTID,c.ACCOUNTID) is not null '+
			
				(lyear == year ? 'and YEAR_=\''+year +'\' ' : 'and YEAR_ in (\''+year+'\',\''+lyear+'\') ')+

				'and BRAND_XIN=\'迈克\'  '+
				//' and a.pk_cubasdoc in (\'0001A0100000003HCRWM\',\'0001A0100000003DSJ1N\',\'0001A0100000006T8HVG\',\'0001ZG10000000A4IUBQ\',\'0001A0100000003DSJ1N\') '+

				'group by nvl(b.ACCOUNTID,c.ACCOUNTID),com.unitcode,pk_cubasdoc,INVCLSFYJNAME '+
				'having sum(case when year_=\''+lyear +'\' and (FLOOR((ltrim(MONTH_,\'0\')-1)/3)+ 1) <='+lquarter+' then nvl(ASSIGNAMOUNT__C,0)-nvl(TASKNMNY,0) else null end) != 0 ';
    }
    @Future(callout=true)
    public  static void  asycnLockNC ( String comcode,List<String > accPks ,String tag ){
        sycnLockNC(comcode,accPks,tag);
    }
    public  static void  sycnLockNC ( String comcode,List<String > accPks ,String tag ){
    
    	String url = Label.NCExchangeInterface;//'https://esb.maccura.com:9088/api/Domain/univer/dbbus/search';
    	
        Map<String, String >dataMap = new Map<String,String>();
       
        //测试 NCTEST 
        dataMap.put('source','NC');
        dataMap.put('tag',tag );

        dataMap.put('pk','\''+String.join(accPks,'\',\'')+'\'');
        dataMap.put('gsbm','\''+comcode+'\'');

   

        System.debug(  comcode +'==>'+JSON.serialize(dataMap));

        //请求
        HttpRequest req = new HttpRequest();
       // req.setBody(JSON.serialize(data) );
        req.setMethod('POST');
        //req.setHeader('Content-Type','text/plain');
        req.setHeader('Content-Type','application/x-www-form-urlencoded ; charset=utf-8');
        req.setEndpoint(url+'?data='+JSON.serialize(dataMap));
        HttpResponse res = Utils.postRequest(req, 2);
        String sycmsg = '';
      ///返回结果处理
        if (res.getStatusCode() == 200) {
            System.debug(res.getBody());
            Map<String,Object> r = null;
              //如果是测试
                if(Test.isRunningTest()){
                  Map<String,Object>  resBody= new Map<String,Object>();
                  resBody.put('code','0');
                  resBody.put('result','{\"result\":\"该SQL语句影响的记录有1条\",\"code\":\"0\",\"msg\":\"success\"}');
                    r =  resBody;
                }else{
                  r= (Map<String,Object> ) JSON.deserializeUntyped(res.getBody());
                }
          if(r.get('code') == 0 || r.get('code') == '0'){
                Map<String,Object> rs = (Map<String,Object>) JSON.deserializeUntyped(((String)r.get('result')));
                System.debug(rs.get('result') != '该SQL语句影响的记录有0条');
              if( (rs.get('code') == 0 || rs.get('code') == '0' ) ){
                   

                    sycmsg = 'OK';
                   
               }else{
                    sycmsg = res.getBody();
               }

	        }else{

	            sycmsg = '同步客户未达成任务量标记失败 : '+String.valueOf(r.get('msg'));
	        }

	    }else{
	         sycmsg = '同步客户未达成任务量标记失败 : '+res.getBody();
	    }

        saveLog(comcode,sycmsg);
	   // sycmsg = 'test';
	
    }
    public static void  saveLog( String comcode ,String message){
            Integer year = System.now().year();
            Integer quarter = Integer.valueOf((System.now().month()-1) / 3 +1 );
            //判断任务是否完成
            String only = 'GetUnfinishAssignTaskShceduler'+year + quarter;
            List<SchedulerExcuetLog__c> seList =  [select Id , Only__c,Message__c , IsFinished__c , Stage1__c,Stage2__c,Stage3__c,Stage4__c from SchedulerExcuetLog__c  where Only__c =:only ];
            ///任务完成了
            SchedulerExcuetLog__c se =seList[0] ;// seList.size() >0 ? seList[0] : new SchedulerExcuetLog__c(Only__c = only);
            
            String subonly = only +comcode;
            Boolean isfinsh = message == 'OK';

            //se.Message__c
            SchedulerExcuetLog__c subLog =  new SchedulerExcuetLog__c(relateLog__c =se.Id,Message__c=message.substring(0, message.length() >= 256 ? 255:message.length() ) ,Only__c = subonly,IsFinished__c = isfinsh );
            upsert subLog Only__c;
            if(!isfinsh || System.Test.isRunningTest()){

                sendMail(subLog.Id);
               
                

            }
                


    }
    public static void sendMail(String seId ){
        Messaging.reserveSingleEmailCapacity(1);
        List<Messaging.SingleEmailMessage> mList = new List<Messaging.SingleEmailMessage>();
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        String[] toAddresses = new String[] {Label.Error_mail};
        mail.setToAddresses(toAddresses);
        //mail.setReplyTo('support@acme.com');
        mail.setSenderDisplayName('Salesforce');
        mail.setSubject('同步客户未达成任务量标记失败:' );
        mail.setBccSender(false);
        mail.setUseSignature(false);
        mail.setPlainTextBody('同步客户未达成任务量标记失败!');
        mail.setHtmlBody('<a href=https://ap7.salesforce.com/'+seId+'>点击查看详情!'+seId+'</a>');
        mList.add(mail);
        if(mList.size() > 0  )Messaging.sendEmail(mList);
    }

    public static String  asycnUnlockNC( Set<String> comcodes ,String  accPks ,String tag,String apdId  ){
        String url = Label.NCExchangeInterface;//'https://esb.maccura.com:9088/api/Domain/univer/dbbus/search';
        
        Map<String, String >dataMap = new Map<String,String>();
        //测试 NCTEST
        dataMap.put('source','NC');
        dataMap.put('tag',tag );

        //dataMap.put('pk','\''+String.join(accPks,'\',\'')+'\'');
        dataMap.put('pk',accPks);
        dataMap.put('gsbm','\''+String.join(new List<String>(comcodes),'\',\'')+'\'');


        //Map<String,String> data = new Map<String,String>();
       // data.put('data', JSON.serialize(dataMap));

        System.debug(JSON.serialize(dataMap));        

        //请求
        HttpRequest req = new HttpRequest();
        //req.setBody(JSON.serialize(data) );
        req.setMethod('POST');
        //req.setHeader('Content-Type','text/plain');
        //req.setEndpoint(url);
        req.setHeader('Content-Type','application/x-www-form-urlencoded ; charset=utf-8');
        req.setEndpoint(url+'?data='+JSON.serialize(dataMap));
        HttpResponse res = Utils.postRequest(req, 2);
        String sycmsg = '';
      ///返回结果处理
        if (res.getStatusCode() == 200) {
            System.debug(res.getBody());
            Map<String,Object> r = null;
              //如果是测试
                if(Test.isRunningTest()){
                  Map<String,Object>  resBody= new Map<String,Object>();
                  resBody.put('code','0');
                  resBody.put('result','{\"result\":\"该SQL语句影响的记录有1条\",\"code\":\"0\",\"msg\":\"success\"}');
                    r =  resBody;
                }else{
                  r= (Map<String,Object> ) JSON.deserializeUntyped(res.getBody());
                }
          if(r.get('code') == 0 || r.get('code') == '0'){
                Map<String,Object> rs = (Map<String,Object>) JSON.deserializeUntyped(((String)r.get('result')));
              if( (rs.get('code') == 0 || rs.get('code') == '0' ) ){
                    
                    sycmsg = 'OK';

                    update new ApplicationForUnqualifiedDelive__c(Id=apdId , NCLock__c=true);

               }else{
                    sycmsg = '同步客户未达成任务量标记失败 : '+rs.get('result')+rs.get('msg');
               }

            }else{

                sycmsg = '同步客户未达成任务量标记失败 : '+String.valueOf(r.get('msg'));
            }

        }else{
             sycmsg = '同步客户未达成任务量标记失败 : '+res.getBody();
        } 
        return sycmsg;
    }
*/
    
    public static String  asycnUnlockNC( String company ,String  accPks ,String apdId  ){
        String url = Label.UnLockAccount;
        //'https://esb.maccura.com:9088/api/Domain/univer/dbbus/search';
        
        Map<String, String >dataMap = new Map<String,String>();
        //测试 NCTEST
        dataMap.put('name','NCAccountLock');
        dataMap.put('groupTag',accPks+'_'+company );

        //dataMap.put('pk','\''+String.join(accPks,'\',\'')+'\'');
        dataMap.put('status','true');
        dataMap.put('cate','task');
        dataMap.put('description','任务量未达标');

        //Map<String,String> data = new Map<String,String>();
       // data.put('data', JSON.serialize(dataMap));
      
        //请求
        HttpRequest req = new HttpRequest();
        req.setBody('data='+ JSON.serialize(new List<Object>{dataMap}));
        req.setMethod('POST');
        //req.setHeader('Content-Type','text/plain');
        //req.setEndpoint(url);
        req.setHeader('Content-Type','application/x-www-form-urlencoded ; charset=utf-8');
        req.setEndpoint(url);
        HttpResponse res = Utils.postRequest(req, 2);
        String sycmsg = '';
      ///返回结果处理
        if (res.getStatusCode() == 200) {
            System.debug(res.getBody());
            Map<String,Object> r = null;
              //如果是测试
                if(Test.isRunningTest()){
                  Map<String,Object>  resBody= new Map<String,Object>();
                  resBody.put('code','0');
                  resBody.put('result','{\"result\":\"该SQL语句影响的记录有1条\",\"code\":\"0\",\"msg\":\"success\"}');
                    r =  resBody;
                }else{
                  r= (Map<String,Object> ) JSON.deserializeUntyped(res.getBody());
                }
            if(r.get('code') == 0 || r.get('code') == '0'){

                 sycmsg = 'OK';

                update new ApplicationForUnqualifiedDelive__c(Id=apdId , NCLock__c=true);
               

            }else{

                sycmsg = '同步客户未达成任务量标记失败 : '+String.valueOf(r.get('msg'));
            }

        }else{
             sycmsg = '同步客户未达成任务量标记失败 : '+res.getBody();
        } 
        return sycmsg;
    }
    @Future(callout=true)
    public  static void    sycnUnlockNC ( String company ,String  accPks ,String apdId  ){
    
        asycnUnlockNC(company,accPks, apdId );

    }

    /*
     public static  List<Object>  getDetails(Integer year ,Integer quarter ){
    		 String msg = '';

    		
    	   	Map<String,String> data = new Map<String,String>();
            data.put('url','jdbc:oracle:thin:@192.168.30.34:1521:dw');
            data.put('username','dw');
            data.put('password','abc,.123');

            data.put('sql',getSql(year,quarter));

            System.debug('GetUnfinishAssignTaskShceduler==>'+getSql(year,quarter));

            Map<String,Object> paramsJson = new  Map<String,Object>() ;
            paramsJson.put('type','oracle');
            paramsJson.put('data',data);
            Blob key = Blob.valueOf('BCFD3E51207C0CF5');
			
		
			//System.debug(EncodingUtil.base64Encode(key));

			Blob d = Blob.valueOf(JSON.serialize(paramsJson));
			String  encrypted = EncodingUtil.base64Encode(Crypto.encrypt('AES128', key, key, d));
			//System.debug(encrypted);

            String url = Label.CoustomQueryDataInterface;
            url += '?type=CBC&data='+encrypted;

			System.debug(url);
            HttpRequest req =  new HttpRequest();
            req.setEndpoint(url);
            req.setMethod('GET');
	        //设置提交超时时间(毫秒)
	        req.setTimeout(65000);
	        Http httpProtocol = new Http();
	        HttpResponse res = null;
	       
	        //连接超时标记	        
            
                if(Test.isRunningTest()){
                    res = new HttpResponse();
                    res.setHeader('Content-Type','application/x-www-form-urlencoded ; charset=GB2312');
                    res.setBody('result=0&confirm_time=2017-01-23 10:15:26&id=2001063&replys=[{"callmdn":"10656584854","mdn":"13929512501","content":"B","reply_time":"2017-01-01 16:37:31","id":"2001062"},{"callmdn":"10656485545","mdn":"18122266563","content":"A","reply_time":"2017-01-01 10:15:26","id":"2001063"}]');
                    res.setStatusCode(200);
                }else{
                    res = httpProtocol.send(req);
                    System.debug(res.getBody());

                }

                if (res.getStatusCode() == 200) {
				    Map<String,Object> r = null;
	              //如果是测试
	                if(Test.isRunningTest()){
	                   Map<String,Object>  resBody= new Map<String,Object>();
	                   resBody.put('code','0');
	                   resBody.put('result','{"result":[{"CURRENTTASK":"6","INVCLSFYJNAME":"血液","TASK":"6","PK_CUBASDOC":"0001A010000000687O2A","UNFINISHTASK":"3.0539","UNITCODE":"BJMK","ACCOUNTID":"0010I00001ak46XQAQ"}],"code":"0","msg":"success"}');
	                    r =  resBody;
	                }else{
	                   r= (Map<String,Object> ) JSON.deserializeUntyped(res.getBody());
	                }
    		        if(r.get('code') == 0 || r.get('code') == '0'){
    		             Map<String,Object> rs = (Map<String,Object>) JSON.deserializeUntyped(((String)r.get('result')));
    		              if( rs.get('code') == '0'){
    		                  return (List<Object>)rs.get('result')  ;

    		               }else{
    		                 msg = String.valueOf(rs.get('result_msg'));
    		               }

    		        }else{
    		          msg = '获取未达成任务量数据失败 : '+String.valueOf(r.get('msg'));
    		      
    		        }

		        }else{
		            msg = '获取未达成任务量数据失败 : '+res.getBody();
		        }
                
         throw new DmlException(msg);

    }*/

}